#include "mixereditsentences.h"
#include "ui_mixereditsentences.h"
#include <QSqlRelationalDelegate>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QMessageBox>
#include <QQueue>

MixerEditSentences::MixerEditSentences(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MixerEditSentences)
{
    ui->setupUi(this);
    smodel = new QSqlRelationalTableModel(this);
    smodel->setTable("mix_sentences");
    smodel->setRelation(1, QSqlRelation("mix_themes", "tid", "teng"));
    smodel->setSort(1, Qt::AscendingOrder);
    smodel->select();
    smodel->setHeaderData(1, Qt::Horizontal, tr("Theme name"));
    smodel->setHeaderData(2, Qt::Horizontal, tr("English sentence"));
    smodel->setHeaderData(3, Qt::Horizontal, tr("Grouping"));
    smodel->setHeaderData(4, Qt::Horizontal, tr("Hungarian sentence"));
    ui->tableView_Sentences->setModel(smodel);
    ui->tableView_Sentences->setItemDelegate(new QSqlRelationalDelegate(this));
    ui->tableView_Sentences->hideColumn(0);
    ui->tableView_Sentences->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);
    ui->tableView_Sentences->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
    ui->tableView_Sentences->horizontalHeader()->setResizeMode(3, QHeaderView::ResizeToContents);
    ui->tableView_Sentences->horizontalHeader()->setResizeMode(4, QHeaderView::Stretch);
    QRegExp rx("[1-9]*");
    groupingValidator = new QRegExpValidator(rx, this);
    rx.setPattern("^(?!\\s)((?!\\*)(?!\\s\\s).)*$");
    sentenceValidator = new QRegExpValidator(rx, this);
    ui->lineEdit_NewGrouping->setValidator(groupingValidator);
    ui->lineEdit_NewEnglish->setValidator(sentenceValidator);
    ui->lineEdit_NewHungarian->setValidator(sentenceValidator);
    themeSelectorsFill();
}

MixerEditSentences::~MixerEditSentences()
{
    delete smodel;
    delete groupingValidator;
    delete sentenceValidator;
    delete ui;
}

void MixerEditSentences::themeSelectorsFill()
{
    ui->comboBox_SelectTheme->addItem(tr("*All*"), 0);
    QSqlQuery query("SELECT * FROM mix_themes ORDER BY teng");
    while (query.next()) {
        int idvalue = query.value(0).toInt();
        QString stringvalue(query.value(1).toString());
        stringvalue.append(" | " + query.value(2).toString());
        ui->comboBox_NewTheme->addItem(stringvalue, idvalue);
        ui->comboBox_SelectTheme->addItem(stringvalue, idvalue);
    }
}

void MixerEditSentences::fetchAllDataFromDB()
{
    while (smodel->canFetchMore())
        smodel->fetchMore();
}

void MixerEditSentences::searchThisRow(int id)
{
    for (int row = 0; row < smodel->rowCount(); ++row) {
        QSqlRecord record = smodel->record(row);
        if (record.value("sid").toInt() == id) {
            ui->tableView_Sentences->selectRow(row);
            break;
        }
    }
}

void MixerEditSentences::on_comboBox_SelectTheme_currentIndexChanged(int index)
{
    int itemdata = ui->comboBox_SelectTheme->itemData(index).toInt();
    if (itemdata)
        smodel->setFilter("theme=" + QString::number(itemdata));
    else
        smodel->setFilter("");
    smodel->select();
    fetchAllDataFromDB();
    ui->comboBox_NewTheme->setCurrentIndex((index == 0) ? 0 : index - 1);
}

void MixerEditSentences::on_pushButton_DeleteSelected_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView_Sentences->selectionModel();
    QModelIndexList indexes = selectionModel->selectedRows();
    int selnr = indexes.count();
    if (!selnr) {
        QMessageBox::information(this, tr("No row selected"), tr("Not selected a row either."));
        return;
    }
    bool yesToAll = false;
    QMessageBox::StandardButtons questionButtons;
    if (selnr > 1)
        questionButtons = QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll;
    else
        questionButtons = QMessageBox::Yes | QMessageBox::No;
    for (int i = 0; i < selnr; ++i) {
        int row = indexes.at(i).row();
        int id = smodel->record(row).value(0).toInt();
        QString sentence = smodel->record(row).value(2).toString();
        int answer = 0;
        if (!yesToAll) {
            QString message(tr("Delete the sentence:<br><b>"));
            message.append(sentence);
            message.append(tr("</b>?"));
            answer = QMessageBox::question(this, tr("Are you sure?"), message, questionButtons, QMessageBox::No);
        }
        if (answer == QMessageBox::YesToAll)
            yesToAll = true;
        if (answer == QMessageBox::NoToAll)
            break;
        if (yesToAll || answer == QMessageBox::Yes) {
            QSqlQuery delquery;
            delquery.prepare("DELETE FROM mix_sentences WHERE sid=:sid");
            delquery.bindValue(":sid", id);
            delquery.exec();
        }
    }
    smodel->select();
    fetchAllDataFromDB();
}

void MixerEditSentences::on_actionNewSentencesChanged_triggered()
{
    int newEnLen = ui->lineEdit_NewEnglish->text().length();
    int newHuLen = ui->lineEdit_NewHungarian->text().length();
    QString enstring(ui->lineEdit_NewEnglish->text());
    QString grpstr(ui->lineEdit_NewGrouping->text());
    QString grouptestString;
    bool groupingOK = sentenceGroupingCheck(enstring, grpstr, grouptestString);
    if (groupingOK && newEnLen > 0 && newHuLen > 0)
        ui->pushButton_SubmitNew->setEnabled(true);
    else
        ui->pushButton_SubmitNew->setEnabled(false);
    if (groupingOK)
            ui->label_NewGroupingPreview->setText("<b>[OK]</b><br>" + grouptestString);
    else
        ui->label_NewGroupingPreview->setText("<b>[FAIL]</b><br>" + grouptestString);
}

bool MixerEditSentences::sentenceGroupingCheck(QString &instring, QString &grpstr, QString &outstring)
{
    QStringList splited = instring.split(" ");
    int wordcnt = splited.count();
    int grpstringlength = grpstr.length();
    int pos = 0;
    if (wordcnt == 1 && instring.length() == 0)
        wordcnt = 0;
    for (int i = 0; i < grpstringlength; ++i) {
        int cwords = grpstr.mid(i, 1).toInt();
        outstring.append("<b>{</b>");
        for (int w = 0; w < cwords; ++w) {
            if (pos < wordcnt)
                outstring.append(splited.at(pos));
            else
                outstring.append("<b>+</b>");
            if (cwords > 1)
                outstring.append(" ");
            ++pos;
        }
        outstring.append("<b>}</b> ");
    }
    for (int i = pos; i < wordcnt; ++i) {
        outstring.append("<b>-</b> ");
    }
    if (pos == 0 || pos == wordcnt)
        return true;
    else
        return false;
}

void MixerEditSentences::on_pushButton_SubmitNew_clicked()
{
    int index = ui->comboBox_NewTheme->currentIndex();
    if (index < 0) {
        QMessageBox::information(this, tr("No themes set."), tr("No themes defined, please add least one theme first from the themes editor!"));
        return;
    }
    int thid = ui->comboBox_NewTheme->itemData(index).toInt();
    QSqlQuery query;
    query.prepare("INSERT INTO mix_sentences (theme, seng, grouping, shun) VALUES (:thid, :seng, :grp, :shun)");
    query.bindValue(":thid", thid);
    query.bindValue(":seng", ui->lineEdit_NewEnglish->text().trimmed());
    query.bindValue(":grp", ui->lineEdit_NewGrouping->text());
    query.bindValue(":shun", ui->lineEdit_NewHungarian->text().trimmed());
    query.exec();
    int newsid = query.lastInsertId().toInt();
    ui->lineEdit_NewEnglish->clear();
    ui->lineEdit_NewHungarian->clear();
    ui->lineEdit_NewGrouping->clear();
    smodel->select();
    searchThisRow(newsid);
}

void MixerEditSentences::on_pushButton_CheckGrouping_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView_Sentences->selectionModel();
    QModelIndexList indexes = selectionModel->selectedRows();
    int selnr = indexes.count();
    bool onlyStat = false;
    if (!selnr || selnr > 19)
        onlyStat = true;
    QString messageStr;
    int ok = 0;
    int err = 0;
    QQueue<int> errors;
    for (int i = 0; i < selnr; ++i) {
        int row = indexes.at(i).row();
        QString sentence = smodel->record(row).value(2).toString();
        QString grp = smodel->record(row).value(3).toString();
        QString groupedstr;
        bool isGroupedOk = sentenceGroupingCheck(sentence, grp, groupedstr);
        if (isGroupedOk)
            ++ok;
        else {
            ++err;
            errors.enqueue(smodel->record(row).value(0).toInt());
        }
        if (!onlyStat)
            messageStr.append(groupedstr + "<hr>");
    }
    messageStr.append(tr("Okay: %n, ", "", ok));
    messageStr.append(tr("Errors: %n.", "", err));
    QMessageBox::information(this, tr("Grouping test"), messageStr);
    if (err) {
        int answer = QMessageBox::question(this, tr("Show errors?"), tr("Would like to see the errors?"), QMessageBox::Yes, QMessageBox::No);
        if (answer == QMessageBox::Yes) {
            QString filter;
            while (errors.count())
                filter.append("sid=" + QString::number(errors.dequeue()) + " or ");
            filter.append("0");
            smodel->setFilter(filter);
            smodel->select();
            fetchAllDataFromDB();
        }
    }
}
